package project

import (
	"autoDeploy/config"
	"autoDeploy/dao/myselfMysql"
	"autoDeploy/models"
	"autoDeploy/utils/DingTalk"
	"autoDeploy/utils/Docker"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"strconv"
)

// mysql 连接实例
var db, _ = myselfMysql.CreateMySQLClient(config.MysqlDb)

// GetUserGitInfos
//
// 描述信息： 根据用户 ID 查询并返回用户所在所有项目的 Git 信息
//
// Param：
//
//	db ：数据库连接实例
//	userID ：用户 ID
//
// Return：
//
//	[]GitProDetails ：用户的所有项目 Git 信息列表
//	error ：错误信息
func GetUserGitInfos(userID uint64) ([]ProDetails, error) {
	// 获取用户所在的所有团队 ID 切片
	teamIDs, err := models.GetUserTeamIDs(db, userID)
	if err != nil {
		return nil, err
	}
	fmt.Println("用户团队：", teamIDs)
	//根据团队id切片获取用户所在的团队信息
	teams, err := models.Team{}.GetTeamsByIDs(db, teamIDs)
	//根据团队id切片返回团队的项目信息，如果团队没有项目则不返回
	//封装数据
	var projectInfo []ProDetails
	var length = len(teamIDs)
	for i := 0; i < length; i++ {
		projectID, _ := models.GetProjectIDByTeamID(db, teamIDs[i])
		//如果团队有项目则进行
		if projectID != 0 {
			projectDetails, err := models.GetGitInfoByProjectID(db, projectID)
			if err != nil {
				// 检查错误是否是“未找到”的错误
				if errors.Is(err, gorm.ErrRecordNotFound) {
					// 如果是“未找到”的错误，返回 nil 和 nil（表示没有错误）
					continue
				}
				// 如果是其他错误，返回错误
				return nil, err
			}
			projectInfo = append(projectInfo, ProDetails{
				ID:                   projectDetails.ID,
				CaptainID:            teams[i].CaptainUserID,
				ProjectID:            projectDetails.ID,
				ProjectName:          projectDetails.ProjectName,
				ProjectOwnerName:     projectDetails.ProjectOwnerName,
				ProjectOwnerHTMLURL:  projectDetails.ProjectOwnerHTMLURL,
				ProjectOwnerEmail:    projectDetails.ProjectOwnerEmail,
				ProjectGitURL:        projectDetails.ProjectGitURL,
				RepositoryGitHTTPURL: projectDetails.RepositoryGitHTTPURL,
				CommitsURL:           projectDetails.CommitsURL,
				ProjectLanguage:      projectDetails.ProjectLanguage,
				Path:                 projectDetails.Path,
			})

		}
	}

	return projectInfo, nil
}

//	DeployProject
//
// 描述信息： 使用用户id，git项目地址进行部署
//
// Param：
//
//	userID ：用户id
//	projectURL ：git项目地址
//
// Return：
//
//	int ：状态码 0表示失败，1表示成功
//	error ：错误信息
func DeployProject(userID uint64, projectURL string) (int, error) {
	//根据项目地址查询项目id
	projectId, err := models.GetProjectIDByGitAddress(db, projectURL)
	if err != nil {
		return 0, err
	}
	//根据项目id查询团队id
	teamID, err := models.GetTeamIDByProjectID(db, projectId)
	if err != nil {
		return 0, err
	}
	//根据项目地址查找git的path
	gitProDetail, err := models.GetGitInfoByProjectID(db, projectId)
	if err != nil {
		return 0, err
	}

	path := gitProDetail.Path
	port, err := models.GetPortByGitAddress(db, projectURL)
	if err != nil {

		return 0, err
	}
	userIdStr := strconv.FormatUint(userID, 10)
	teamIdStr := strconv.FormatUint(teamID, 10)

	fmt.Println(projectURL, userIdStr, teamIdStr, path, port)
	git, s, err := Docker.DeployFromGit(projectURL, userIdStr, teamIdStr, path, port)
	if err != nil {
		fmt.Println(err)
		return 0, err
	}
	fmt.Println(git, s)
	//根据团队id查询团队信息
	t, _ := models.Team{}.GetTeamByID(db, teamID)
	//根据项目id查询项目信息
	p, _ := models.GetProjectByID(db, projectId)
	//查看项目的端口
	url, err := GetIPAndPort(p.GitAddress)
	if err != nil {
		fmt.Println(err)
		return 0, err
	}
	err = DingTalk.SendMessageToDingTalkDeploySuccess(t.Address, p.Name, t.Name, url)
	if err != nil {
		fmt.Println(err)
		return 0, err
	}
	return 1, nil
}

//	SavePushMsg
//
// 描述信息： 将推送者和git项目信息插入数据库中
//
// Param：
//
//	projectDetail ：git项目信息对象
//	pusher ：推送这信息对象
//
// Return：
//
//	int ：状态码，0表示插入失败，1表示插入成功
//	error ：错误信息
func SavePushMsg(projectDetail ProjectDetails, pusher Pusher) (int, error) {
	projectId, err := models.GetProjectIDByGitAddress(db, projectDetail.Project.GitHTTPURL)
	if err != nil {
		return 0, err
	}
	//插入到git_pro_details中
	err = models.GitProDetails{}.InsertGitProDetails(db, projectId,
		projectDetail.Project.Name,
		projectDetail.Project.Owner.Name,
		projectDetail.Project.Owner.HTMLURL,
		projectDetail.Project.Owner.Email,
		projectDetail.Project.GitHTTPURL,
		projectDetail.Repository.GitHTTPURL,
		pusher.Commits[0].URL,
		projectDetail.Project.Language,
		projectDetail.Project.Path)
	if err != nil {
		return 0, err
	}

	//插入到pro_pusher_msg中
	err = models.ProPusherMsg{}.InsertProPusherMsg(db,
		projectId,
		pusher.Pusher.Name,
		pusher.Pusher.Email,
		pusher.Sender.HTMLURL,
		pusher.Commits[0].Message,
		pusher.Compare,
		pusher.Commits[0].Timestamp)
	if err != nil {
		return 0, err
	}

	return 1, nil
}

// GetCaptainId 根据项目GitHttpUrl查询团队队长id
func GetCaptainId(db *gorm.DB, GitHttpURL string) (uint64, error) {
	//先查项目id
	proId, err := models.GetProjectIDByGitAddress(db, GitHttpURL)
	if err != nil {
		return 0, fmt.Errorf("service层 TagDeploy 开始部署前首先查询项目的id 出错:%s", err.Error())
	}
	//根据项目id查团队id
	teamId, err := models.GetTeamIDByProjectID(db, proId)
	if err != nil {
		return 0, fmt.Errorf("service层 TagDeploy 开始部署前首先查询项目对应的团队的id 出错:%s", err.Error())
	}
	//根据团队id查询队长id
	team, err := models.Team{}.GetTeamByID(db, teamId)
	if err != nil {
		return 0, fmt.Errorf("service层 TagDeploy 开始部署前,根据团队id查询团队出错:%s", err.Error())
	}
	return team.CaptainUserID, nil
}

func TagDeploy(TagEvent ProjectTag) (int, error) {

	//开始部署前首先查询队长的id
	captainId, _ := GetCaptainId(db, TagEvent.Project.GitHttpURL)
	//查看当前 project_tag 表中是否已经有记录
	exist, err := models.ProjectTag{}.ExistsByGitURL(db, TagEvent.Project.GitHttpURL)
	if err != nil {
		return 0, fmt.Errorf("service层 TagDeploy 查看当前 project_tag 表中是否已经有记录出错:%s", err.Error())
	}

	//如果已经存在记录，则查看版本号是否一致
	if exist {
		projectTag, err := models.ProjectTag{}.GetTagVersionByGitURL(db, TagEvent.Project.GitHttpURL)
		if err != nil {
			return 0, fmt.Errorf("service层 TagDeploy 则查看版本号是否一致出错:%s", err.Error())
		}
		// 如果一致则什么也不做
		if projectTag == TagEvent.TagVersion {
			return 1, nil
		} else {
			//如果不一致则更新当前的值，并执行部署逻辑
			err = models.ProjectTag{}.UpdateTagVersionByGitURL(db, TagEvent.Project.GitHttpURL, TagEvent.TagVersion)
			if err != nil {
				return 0, fmt.Errorf("service层 TagDeploy 更新版本号出错:%s", err.Error())
			}

			//开始部署
			_, err = DeployProject(captainId, TagEvent.Project.GitHttpURL)
			if err != nil {
				return 0, fmt.Errorf("service层 TagDeploy 开始部署出错:%s", err.Error())
			}

			return 1, nil
		}
	} else {
		//如果不存在记录 则先插入再部署
		projectId, err := models.GetProjectIDByGitAddress(db, TagEvent.Project.GitHttpURL)
		if err != nil {
			return 0, fmt.Errorf("service层 TagDeploy 不存在记录,查询项目id出错:%s", err.Error())
		}
		_, err = models.ProjectTag{}.InsertProjectTag(db, projectId, TagEvent.Project.GitHttpURL, TagEvent.TagVersion)
		if err != nil {
			return 0, fmt.Errorf("service层 TagDeploy 不存在记录,查询项目id出错:%s", err.Error())
		}
		//开始
		_, err = DeployProject(captainId, TagEvent.Project.GitHttpURL)
		if err != nil {
			return 0, fmt.Errorf("service层 TagDeploy 开始部署出错:%s", err.Error())
		}
		return 1, nil
	}
}

// GetIPAndPort 根据git_address获取ip和端口号
func GetIPAndPort(gitAddress string) (string, error) {
	//ip, err := GetPC.GetPublicIP()
	//if err != nil {
	//	return "", errors.New("获取ip地址失败：" + err.Error())
	//}
	port, err := models.GetPortByGitAddress(db, gitAddress)
	if err != nil {
		return "", errors.New("获取端口地址失败：" + err.Error())
	}
	return "http://129.211.69.41:" + port, nil
}

//	GetProjectSum
//
// 描述信息：根据用户id获取用户的团队数量
//
// Param：
//
//	userID ：用户id
//
// Return：
//
//	int ：团队数量
//	error ：错误信息
func GetProjectSum(userID uint64) (int, error) {
	res, err := models.GetUserTeamsAndRoles(db, userID)
	if err != nil {
		return 0, fmt.Errorf("service层根据用户id获取团队数量失败：%v", err.Error())
	}
	length := len(res)
	return length, nil
}

//	GetMemberSum
//
// 描述信息： 根据用户id返回所有的团队成员总数
//
// Param：
//
//	userID ：用户id
//
// Return：
//
//	int32 ：成员个数
//	error ：错误信息
func GetMemberSum(userID uint64) (int32, error) {
	//首先根据用户id获取所有的团队id
	teams, err := models.GetUserTeamIDs(db, userID)
	if err != nil {
		return 0, fmt.Errorf("service层根据用户id获取团队列表失败%v", err.Error())
	}
	//查询每个团队id的人数，然后累加即可
	var sum int32
	for _, team := range teams {
		tmp, _, err := models.GetTeamMemberIDs(db, team)
		if err != nil {
			return 0, fmt.Errorf("service层根据用户id获取团队成员个数失败%v", err.Error())
		}
		sum += int32(tmp)
	}
	return sum, nil
}
